<template>
  <div id="roam"> 
  </div>
</template>
<script>
import * as THREE from 'three'
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls'
const TWEEN = require('@tweenjs/tween.js')
import posximgUrl from '../assets/posx.jpg'
import negximgUrl from '../assets/negx.jpg';
import posyimgUrl from '../assets/posy.jpg';
import negyimgUrl from '../assets/negy.jpg';
import poszimgUrl from '../assets/posz.jpg';
import negzimgUrl from '../assets/negz.jpg';
import pximgUrl from '../assets/px.jpg';
import nximgUrl from '../assets/nx.jpg';
import pyimgUrl from '../assets/py.jpg';
import nyimgUrl from '../assets/ny.jpg';
import pzimgUrl from '../assets/pz.jpg';
import nzimgUrl from '../assets/nz.jpg';
import arrow from '../assets/arrow.png';
import plate from '../assets/plate.png'
export default {
  name: 'roam',
  data(){
      return{
        imgSrc: [posximgUrl,negximgUrl,posyimgUrl,negyimgUrl,poszimgUrl,negzimgUrl],
        box2ImgSrc:[pximgUrl,nximgUrl,pyimgUrl,nyimgUrl,pzimgUrl,nzimgUrl],
        arrow,
        plate,
      }
  },
  methods:{
      roam_test(){
        let container = document.getElementById("roam");
        container.style.height = window.innerHeight + "px";
        let scene = new THREE.Scene();
        let geometry = new THREE.BoxGeometry(1000, 1000, 1000);
        let textureLoader = new THREE.TextureLoader();
        let materialArray = [];
        for (let i = 0; i < 6; i++){
            materialArray.push( new THREE.MeshBasicMaterial({
                map: textureLoader.load(this.imgSrc[i]),
                side: THREE.DoubleSide
            }));
        }
        //第一个天空盒  
        let mesh = new THREE.Mesh(geometry, materialArray); 
        scene.add(mesh);

        let geometry2 = new THREE.BoxGeometry(1000, 1000, 1000);
        let materialArray2 = [];
        for (let i = 0; i < 6; i++){
            materialArray2.push( new THREE.MeshBasicMaterial({
                map: textureLoader.load(this.box2ImgSrc[i]),
                side: THREE.DoubleSide
            }));
        }
        //第二个天空盒，与第一个天空盒在x轴上相邻    
        let mesh2 = new THREE.Mesh(geometry2, materialArray2);
        //这里由于纹理并不连贯所以不能完全紧贴，不然渲染出来的效果会有重叠
        //todo
        mesh2.translateX(1001);
        scene.add(mesh2)

        let axisHelper = new THREE.AxesHelper(1000);
        scene.add(axisHelper); 
        
        let width = container.clientWidth; 
        let height = container.clientHeight; 
        let camera = new THREE.PerspectiveCamera(90, width/height, 0.1, 10000);
        camera.position.set(100,100,100); 
        let cameraHelper = new THREE.CameraHelper(camera);
        scene.add(cameraHelper);
        
        let renderer = new THREE.WebGLRenderer();
        renderer.setSize(width, height); //设置渲染区域尺寸
        renderer.setClearColor(0xffffff, 1); //设置背景颜色
        container.appendChild(renderer.domElement); //插入canvas对象

         //创建一个精灵图,作为点击事件的热点
         //精灵图的优点在于始终正对当前视角
        let spriteMaterial = new THREE.SpriteMaterial({
           map:textureLoader.load(plate),
         })
        let spriteArrow = new THREE.Sprite(spriteMaterial);
        spriteArrow.scale.set(100, 100, 100);
        spriteArrow.position.set(500, 0, 0)
        scene.add(spriteArrow);

        //鼠标位置的转换
        //转换前，左上角为（0，0）
        //转换后，画布中心为（0，0）
        let mouse = new THREE.Vector2();
        function mouseMoveEvent(event) {
            mouse.width = (event.clientX / container.clientWidth) * 2 - 1;
            mouse.height = - (event.clientY / container.clientHeight) * 2 + 1;
        }
        container.addEventListener('mousemove', mouseMoveEvent, false);

        //捕获点击特定模型的点击事件
        let raycaster = new THREE.Raycaster();
        function mouseClickEvent(event) {
            event.preventDefault();
            // 射线捕捉
            raycaster.setFromCamera(mouse, camera);
            let intersects = raycaster.intersectObjects([spriteArrow]);
            if (intersects.length > 0) {
                changeScene();
            }
        }
        container.addEventListener('click', mouseClickEvent, false);

        //控件对象会覆盖camera.lookAt()方法
        let controls = new OrbitControls(camera,renderer.domElement);

        
        function render(){ 
            controls.update();
            TWEEN.update();
            renderer.render(scene, camera); 
            requestAnimationFrame(render);
        }
        render();

        function changeScene() {
            spriteArrow.visible = false;
            //使用tween.js实现过度效果
            let position = {
              x: camera.position.x,
              y: camera.position.y,
              z: camera.position.z,
              a: controls.target.x,
              b: controls.target.y,
              c: controls.target.z,
            };
            let tween = new TWEEN.Tween(position);
            
            //这里目的值设置为固定值主要是为了调整轨道控制器的中心
            //这里需要继续优化
            tween.to({ x: mesh2.position.x,y:mesh2.position.y,z:mesh2.position.z,a:1100,b:0,c:0}, 5000);
            tween.onUpdate(function(object){
            camera.position.x = object.x;
            camera.position.y = object.y
            camera.position.z = object.z;
            camera.updateProjectionMatrix();
            controls.target.x = object.a;
            controls.target.y = object.b;
            controls.target.z = object.c;
            })
            tween.start();            
        }
      }
      
  }, 
  mounted () {
      this.roam_test();
 }
}
</script>

<style scope>
</style>